package singlethread;
import java.net.URL;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Provides a place to store urls and way to retrieve urls not yet visited.
 * @author Darin
 * @author Kirk Leonard
 * @author John Patanian
 * @version Autumn 2009
 */
public class URLBucket 
{
  /**
  * The set of visited urls.
  */
  private Set<URL> my_visited_urls;

  /**
  * The set of unvisited urls.
  */
  private Set<URL> my_unvisited_urls; 

  /**
  * The count of how many links per page.
  */
  private int my_link_count;

  /**
  * The public constructor setting up a new URL bucket.
  */
  public URLBucket()
  {
    my_link_count = 0;
    my_visited_urls = new HashSet<URL>();
    my_unvisited_urls = new HashSet<URL>();
  }

  /**
  *  Adds a url to the unvisited set.
  * @param the_url The url to add to the unvisited set.
  */
  public void addURL(final URL the_url)
  {
    if (the_url == null)
    {
      return;
    }
    
    my_link_count++;
    my_unvisited_urls.add(the_url);
  }

  /**
  * gets a url, checks to make sure that we haven't visited it yet, throws it away.
  * if we have and gets the next one...until we have an unvisited url to get or
  * we've run out of urls
  * @return Returns the URL.
  */
  public URL getURL()
  {
    final Iterator<URL> a_url_iterator = my_unvisited_urls.iterator();

    while (a_url_iterator.hasNext())
    {
      final URL a_url = a_url_iterator.next();
      a_url_iterator.remove();

      if (!(my_visited_urls.contains(a_url)))
      {
        my_visited_urls.add(a_url);
        return a_url;
      }
    }
    return null;
  }

  /**
  * The number of unvisited urls.
  * @return An integer count of the unvisited urls.
  */
  public int getUnVisitedSize()
  {
    return my_unvisited_urls.size();
  }

  /**
  * The number of visited urls.
  * @return An integer count of the visited urls.
  */
  public int getVisitedSize()
  {
    return my_visited_urls.size();
  }

  /**
  * The number of links found.
  * @return The integer link count
  */
  public int getNumLinks()
  {
    return my_link_count;
  }
}
